home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 14.4 KB | 531 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWClpCmd.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWFrameW.hpp"
-
- #ifndef FWCLPCMD_H
- #include "FWClpCmd.h"
- #endif
-
- #ifndef FWPART_H
- #include "FWPart.h"
- #endif
-
- #ifndef FWINTER_H
- #include "FWInter.h"
- #endif
-
- #ifndef FWFRAME_H
- #include "FWFrame.h"
- #endif
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- #ifndef FWSELECT_H
- #include "FWSelect.h"
- #endif
-
- #ifndef FWLINK_H
- #include "FWLink.h"
- #endif
-
- #ifndef FWLNKMGR_H
- #include "FWLnkMgr.h"
- #endif
-
- #ifndef FWSESION_H
- #include "FWSesion.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef FWBARRAY_H
- #include "FWBArray.h"
- #endif
-
- #ifndef SLODFSTR_K
- #include "SLODFStr.k"
- #endif
-
- #ifndef SLODFSTR_H
- #include "SLODFStr.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_Module_OpenDoc_Commands_defined
- #include <CmdDefs.xh>
- #endif
-
- #ifndef SOM_ODClipboard_xh
- #include <Clipbd.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODLinkSpec_xh
- #include <LinkSpec.xh>
- #endif
-
- //========================================================================================
- // Runtime Info
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfcommands
- #endif
-
- FW_DEFINE_AUTO(FW_CClipboardCommand)
-
- //========================================================================================
- // FW_CClipboardCommand class
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand constructor
- //----------------------------------------------------------------------------------------
-
- FW_CClipboardCommand::FW_CClipboardCommand(Environment* ev,
- ODCommandID id,
- FW_CFrame* frame,
- FW_Boolean canUndo)
- : FW_CCommand(ev, id, frame, id == kODCommandCopy ? FALSE :canUndo),
- fUpdateID(kODUnknownUpdate),
- fCloneKind(kODCloneCopy),
- fPasteAsHandler(NULL),
- fSelection(NULL)
- {
- short undoMsgID;
-
- switch (id)
- {
- case kODCommandCopy:
- SetCausesChange(ev, FALSE); // Copy doesn't change the data
- break;
-
- case kODCommandCut:
- fCloneKind = kODCloneCut;
- undoMsgID = FW_kUndoCutMsg;
- break;
-
- case kODCommandPaste:
- fCloneKind = kODClonePaste;
- undoMsgID = FW_kUndoPasteMsg;
- break;
-
- case kODCommandPasteAs:
- fCloneKind = kODClonePaste;
- undoMsgID = FW_kUndoPasteAsMsg;
- break;
-
- case kODCommandClear:
- undoMsgID = FW_kUndoClearMsg;
- break;
-
- default:
- undoMsgID = FW_kDefaultUndoMsg;
- break;
- }
-
- fSelection = frame->GetPresentation(ev)->GetSelection(ev);
-
- if (GetCanUndo(ev))
- {
- FW_CString undoString;
- FW_CString redoString;
-
- ::FW_PrivLoadUndoStrings(ev, undoMsgID, undoString, redoString);
- SetMenuStrings(ev, undoString, redoString);
- }
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand destructor
- //----------------------------------------------------------------------------------------
-
- FW_CClipboardCommand::~FW_CClipboardCommand()
- {
- FW_START_DESTRUCTOR
- delete fPasteAsHandler;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::DoIt
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::DoIt(Environment* ev) // Override
- {
- FW_Boolean canDo = this->IsOKtoEdit(ev);
-
- if (canDo)
- {
- if (GetCanUndo(ev))
- this->SaveUndoState(ev); // save current state, for later Undo
-
- switch (GetCommandID(ev))
- {
- case kODCommandCopy:
- this->Copy(ev);
- break;
-
- case kODCommandClear:
- this->Clear(ev);
- break;
-
- case kODCommandCut:
- this->Cut(ev);
- break;
-
- case kODCommandPaste:
- canDo = this->Paste(ev);
- break;
-
- case kODCommandPasteAs:
- canDo = this->PasteAs(ev);
- break;
- }
- }
-
- if (canDo == FALSE)
- {
- SetCanUndo(ev, FALSE);
- SetCausesChange(ev, FALSE);
- }
- else if (GetCanUndo(ev))
- {
- this->SaveRedoState(ev); // save new state, for later Redo
- }
- }
-
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::Cut
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::Cut(Environment* ev)
- {
- PreCommand(ev);
-
- this->PrivCopy(ev, false); // don't write a link spec for a cut
- fSelection->ClearSelection(ev);
-
- // Give the command subclass a chance to do something
- this->CommandDone(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::Copy
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::Copy(Environment* ev)
- {
- PreCommand(ev);
-
- FW_Boolean allowLinking = (fSelection && fSelection->IsSelectionLinkable(ev));
- this->PrivCopy(ev, allowLinking);
-
- CommandDone(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::Clear
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::Clear(Environment* ev)
- {
- PreCommand(ev);
- fSelection->ClearSelection(ev);
- CommandDone(ev); // Give the command subclass a chance to do something
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::Paste
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CClipboardCommand::Paste(Environment* ev)
- {
- PreCommand(ev);
- return PrivPaste(ev); // will call CommandDone
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::PrivPaste
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CClipboardCommand::PrivPaste(Environment* ev)
- {
- FW_Boolean result = FALSE;
-
- ODStorageUnit* clipBSU = FW_CSession::GetClipboard(ev)->GetContentStorageUnit(ev);
-
- result = GetPart(ev)->GetDataInterchange(ev)->InternalizeData(ev, fSelection->GetSelectedContent(ev), GetFrame(ev), clipBSU, FW_kClipboardStorage, fCloneKind, NULL) != FW_kInternalizeFailed;
-
- if (result)
- {
- // notify OpenDoc clipboard
- fUpdateID = FW_CSession::GetClipboard(ev)->ActionDone(ev, fCloneKind);
-
- // Give the command subclass a chance to do something
- CommandDone(ev);
- }
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::PasteAs
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CClipboardCommand::PasteAs(Environment* ev)
- {
- FW_Boolean result = false;
- FW_VOLATILE(result);
- FW_Boolean handledIt = false;
-
- PreCommand(ev);
-
- FW_TRY
- {
- // Create a PasteAs handler object to do some of the work
- fPasteAsHandler = new FW_MPasteAsHandler(ev, GetFrame(ev));
- result = fPasteAsHandler->HandlePasteAsDialog(ev, fCloneKind, handledIt);
- if (!handledIt)
- {
- SetCommandID(ev, kODCommandPaste);
- result = this->PrivPaste(ev); // just an ordinary paste
- }
- else if (result)
- {
- // notify OpenDoc clipboard
- fUpdateID = FW_CSession::GetClipboard(ev)->ActionDone(ev, fCloneKind);
-
- // if a link was created and established, need to post an End transaction
- if (this->PrivWasLinkEstablished(ev))
- {
- SetActionType(ev, kODEndAction);
- }
-
- // Give the command subclass a chance to do something
- this->CommandDone(ev);
- }
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- result = false; // don't re-throw, just return false
- }
- FW_CATCH_END
-
- if (result == false || GetCommandID(ev) == kODCommandPaste)
- {
- // PasteAs handler either not used or not needed
- delete fPasteAsHandler;
- fPasteAsHandler = NULL;
- }
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::PrivCopy
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::PrivCopy(Environment* ev, FW_Boolean allowLinking)
- {
- ODClipboard* clipboard = FW_CSession::GetClipboard(ev);
-
- //---- We have to invalidate any currently pending link ----
- FW_CLinkManager* linkMgr = GetPart(ev)->GetLinkManager(ev);
- if (linkMgr)
- linkMgr->DeletePendingClipboardLink(ev);
-
- //---- Clear any leftover promises on the clipboard ----
- clipboard->GetContentStorageUnit(ev)->ClearAllPromises(ev);
- GetPart(ev)->GetDataInterchange(ev)->PrivDeletePromises(ev, FW_kClipboardStorage);
-
- //---- Clear all properties and values from the clipboard ----
- clipboard->Clear(ev);
-
- // [HLX] Getting the clipboardSU before calling clipboard->Clear(ev) results in
- // a crash in ExternalizeData when I try to get the draft?????
- ODStorageUnit* clipboardSU = clipboard->GetContentStorageUnit(ev);
-
- //---- Write new data to the clipboard ----
- GetPart(ev)->GetDataInterchange(ev)->ExternalizeData(ev,
- fSelection->GetSelectedContent(ev),
- GetFrame(ev),
- clipboardSU,
- FW_kClipboardStorage,
- fCloneKind);
-
- //---- notify OpenDoc clipboard ----
- fUpdateID = clipboard->ActionDone(ev, fCloneKind);
-
- // ---- Save clipboard update id ----
- GetPart(ev)->GetDataInterchange(ev)->PrivSetClipboardUpdateID(ev, fUpdateID);
-
- // ----- Write out Link Spec if possible -----
- if (allowLinking)
- {
- ODLinkSpec* linkSpec = NULL;
- FW_VOLATILE(linkSpec);
- ODUpdateID updateID = fUpdateID;
- FW_CByteArray data(&updateID, sizeof(ODUpdateID));
-
- FW_TRY
- {
- linkSpec = GetPart(ev)->GetDraft(ev)->CreateLinkSpec(ev, GetPart(ev)->GetODPart(ev), data);
-
- clipboardSU->AddProperty(ev, kODPropLinkSpec);
- linkSpec->WriteLinkSpec(ev, clipboardSU);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- if (linkSpec)
- delete linkSpec;
- FW_THROW_SAME();
- }
- FW_CATCH_END
-
- delete linkSpec;
-
- // If current selection is already published, just re-use its link
- FW_CLinkSource* linkSource = fSelection->DoFindLinkSource(ev);
- if (linkSource)
- linkSource->SetPendingID(ev, updateID);
- else
- linkSource = linkMgr->NewLinkSource(ev, updateID, GetPresentation(ev));
- linkMgr->SetPendingClipboardLink(ev, linkSource);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::UndoIt
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::UndoIt(Environment* ev) // Override
- {
- switch (GetCommandID(ev))
- {
- case kODCommandCut:
- case kODCommandPaste:
- case kODCommandPasteAs:
- {
- FW_CSession::GetClipboard(ev)->ActionUndone(ev, fUpdateID, fCloneKind);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::RedoIt
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::RedoIt(Environment* ev) // Override
- {
- switch (GetCommandID(ev))
- {
- case kODCommandCut:
- case kODCommandPaste:
- case kODCommandPasteAs:
- {
- FW_CSession::GetClipboard(ev)->ActionRedone(ev, fUpdateID, fCloneKind);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::PreCommand
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::PreCommand(Environment* ev)
- {
- FW_UNUSED(ev);
- // User may override; gets called before the command's function is done
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::CommandDone
- //----------------------------------------------------------------------------------------
-
- void FW_CClipboardCommand::CommandDone(Environment* ev)
- {
- FW_UNUSED(ev);
- // User may override; only gets called if the command was successful
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::IsOKtoEdit
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CClipboardCommand::IsOKtoEdit(Environment* ev)
- {
-
- // This used to call fSelection::CanEditSelection, but that's not appropriate for
- // all clipboard actions. In fact, with the current set of sample parts, it's
- // not appropriate for any clipboard actions. If the command architecture remains
- // more or less as it is, then this implementation will probably be removed. Part's
- // will implement any necessary additional testing in their overrides of this method.
-
- FW_Boolean result = FW_CCommand::IsOKtoEdit(ev);
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::GetNewLink
- //----------------------------------------------------------------------------------------
-
- FW_CLinkDestination* FW_CClipboardCommand::GetNewLink(Environment* ev) const
- {
- return fPasteAsHandler ? fPasteAsHandler->GetNewLink(ev) : NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::PrivWasLinkEstablished
- //----------------------------------------------------------------------------------------
- FW_Boolean FW_CClipboardCommand::PrivWasLinkEstablished(Environment* ev)
- {
- FW_CLinkDestination* newLink = this->GetNewLink(ev);
- if (newLink == NULL)
- return false;
-
- // Link was created, but has it been established?
- FW_Boolean result = newLink->IsEstablished(ev);
-
- // If link was created but not established, defer posting an End action
- if (result == false)
- {
- newLink->PrivSetCommandToEndAction(ev, this);
- // When the link is finally established the command will post an End action.
- }
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CClipboardCommand::PrivAddEndAction
- //----------------------------------------------------------------------------------------
- void FW_CClipboardCommand::PrivAddEndAction(Environment* ev)
- {
- AddAction(ev, kODEndAction, NULL, 0, GetUndoString(ev), GetRedoString(ev));
- }
-